package com.devshephard.rpcframework.rpc.runner;

import com.devshephard.rpcframework.rpc.container.GlobalContainer;
import com.devshephard.rpcframework.rpc.factory.channel.SingletonClientMultiChannelFactory;
import com.devshephard.rpcframework.rpc.factory.channel.SingletonServerChannelFactory;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

@Component
@Slf4j
public class NettyMultiRunner {

    private static String currentServerAddress;  //本地Netty地址

    private static String currentServerPort;  //本地Netty端口


    public void run() {

            ExecutorService fixedThreadPool = Executors.newFixedThreadPool(10);

            new Thread(()->{
                    log.info("Enable Rpc Server On Port {}",currentServerPort);
                    SingletonServerChannelFactory singletonServerChannelFactory = new SingletonServerChannelFactory(); //启动服务端
                    singletonServerChannelFactory.startServerChannel(currentServerAddress,currentServerPort);
            },"Netty-Server").start();

            new Thread(()->{

                log.info("Enable Mutli Rpc Client");

                //将channel存入channel容器,并与RPC地址对应
                List<Map<String, Object>> rpcClientAnnotationInfoList = GlobalContainer.getRpcClientAnnotationInfoList();
                for (Map<String, Object> mapv : rpcClientAnnotationInfoList) {

                    SingletonClientMultiChannelFactory singletonClientChannelFactory = new SingletonClientMultiChannelFactory(); //启动客户端
                    String address1 = mapv.get("address").toString();

                    if(!Objects.isNull(address1) && !"".equals(address1)){

                        //解析地址
                        List<String> detailAddressList = Arrays.asList(address1.split(":"));
                        String ipAddress = detailAddressList.get(0);
                        String ipPort = detailAddressList.get(1);

                        try {
                            singletonClientChannelFactory.startClientChannel(ipAddress,ipPort);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }

                        /**
                         * 使用异步的方式进行,防止当多个服务中存在某个服务连接不上从而阻塞使得其他连接没有机会进行
                         */
                        fixedThreadPool.execute(new Runnable() {
                            @Override
                            public void run() {
                                try {
                                    singletonClientChannelFactory.startClientChannel(ipAddress,ipPort);
                                } catch (InterruptedException e) {
                                    e.printStackTrace();
                                }
                            }
                        });

                        ConcurrentHashMap<String, SingletonClientMultiChannelFactory> channelFactoryContainerMap = GlobalContainer.getChannelFactoryContainerMap();
                        channelFactoryContainerMap.put(address1,singletonClientChannelFactory);

                    }
                }

            },"Netty-Client").start();
    }


    public void setEnvironment(Environment environment) {

        this.currentServerAddress = environment.getProperty("rpc.local.address");  //本地Netty地址

        this.currentServerPort = environment.getProperty("rpc.local.port");  //本地Netty端口

    }

}
